package Client.circuitBreaker;

import java.util.concurrent.atomic.AtomicInteger;

public class CircuitBreaker {
    // 熔断器初始状态
    private CircuitBreakerState state = CircuitBreakerState.CLOSED;
    // 失败请求计数
    private AtomicInteger failureCount = new AtomicInteger(0);
    // 成功请求计数
    private AtomicInteger successCount = new AtomicInteger(0);
    // 请求总数
    private AtomicInteger requestCount = new AtomicInteger(0);
    // 失败阈值
    private final int failureThreshold;
    // 半开状态下的成功率阈值
    private final double halfSuccessThreshold;
    // 重置时间周期
    private final long resetTimePeriod;
    // 最后一次失败时间
    private long lastFailureTime;

    public CircuitBreaker(int failureThreshold, double halfSuccessThreshold, long resetTimePeriod) {
        this.failureThreshold = failureThreshold;
        this.halfSuccessThreshold = halfSuccessThreshold;
        this.resetTimePeriod = resetTimePeriod;
    }

    // 根据当前熔断器状态判断是否允许请求
    public synchronized boolean allowRequest() {
        System.out.println("allowRequest状态："+state);
        long currentTime = System.currentTimeMillis();
        switch (state) {
            case OPEN:
                if (currentTime - lastFailureTime > resetTimePeriod) {
                    // 如果已经超过重置时间周期，则进入半开状态
                    state = CircuitBreakerState.HALF_OPEN;
                    // 重置计数
                    resetCounts();
                    // 允许请求
                    return true;
                } else {
                    // 如果没有超过重置时间周期，则不允许请求
                    return false;
                }
            case HALF_OPEN:
                // 半开状态下，允许请求
                requestCount.incrementAndGet();
                return true;
            case CLOSED:
                return true;
            default:
                return false;
        }
    }

    // 记录一次成功的请求
    public synchronized void recordSuccess() {
        if (state == CircuitBreakerState.HALF_OPEN) {
            successCount.incrementAndGet();
            if (successCount.get() >= halfSuccessThreshold * requestCount.get()) {
                state = CircuitBreakerState.CLOSED;
                resetCounts();
            }
        } else {
            resetCounts();
        }
    }

    // 记录一次失败的请求
    public synchronized void recordFailure() {
        failureCount.incrementAndGet();
        lastFailureTime = System.currentTimeMillis();

        if (state == CircuitBreakerState.HALF_OPEN) {
            state = CircuitBreakerState.OPEN;
        } else if (failureCount.get() >= failureThreshold){
            state = CircuitBreakerState.OPEN;
        }
    }

    private void resetCounts() {
        failureCount.set(0);
        successCount.set(0);
        requestCount.set(0);
    }
}

enum CircuitBreakerState {
    CLOSED,    // 关闭
    OPEN,      // 开启
    HALF_OPEN  // 半开启
}